package com.bank.backend.service.impl;

import com.bank.backend.model.vo.UserVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bank.backend.exception.BusinessException;
import com.bank.backend.enums.ErrorCode;
import com.bank.backend.mapper.CardMapper;
import com.bank.backend.mapper.UserMapper;
import com.bank.backend.mapper.TradeMapper;
import com.bank.backend.model.entity.User;
import com.bank.backend.model.entity.Card;
import com.bank.backend.model.entity.Trade;
import com.bank.backend.model.dto.CustomerCreateDTO;
import com.bank.backend.model.dto.CustomerQueryDTO;
import com.bank.backend.model.dto.CustomerUpdateDTO;
import com.bank.backend.model.dto.CardCreateDTO;
import com.bank.backend.service.CustomerManageService;
import com.bank.backend.service.CardManageService;
import com.bank.backend.utils.UserHolder;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bank.backend.result.PageResult;
import org.springframework.util.DigestUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 管理员服务实现类
 */
@Service
@Slf4j
public class CustomerManageServiceImpl extends ServiceImpl<UserMapper, User> implements CustomerManageService {

    @Resource
    private UserMapper userMapper;
    
    @Resource
    private CardMapper cardMapper;

    @Resource
    private CardManageService cardManageService;

    @Resource
    private TradeMapper tradeMapper;

    @Override
    @Transactional
    public void createCustomer(CustomerCreateDTO customerCreateDTO) {
        // 1. 检查当前用户是否为管理员
        User currentUser = UserHolder.getUser();
        if (currentUser == null || !currentUser.getIsAdmin()) {
            throw new BusinessException(40001, "权限不足，只有管理员可以创建客户");
        }
        // 2. 检查身份证号是否已存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pid", customerCreateDTO.getPid());
        queryWrapper.eq("is_deleted", 0);
        User existingUser = userMapper.selectOne(queryWrapper);
        if (existingUser != null) {
            throw new BusinessException(40000, "身份证号已存在");
        }
        // 3. 检查手机号是否已存在
        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("telephone", customerCreateDTO.getTelephone());
        queryWrapper.eq("is_deleted", 0);
        existingUser = userMapper.selectOne(queryWrapper);
        if (existingUser != null) {
            throw new BusinessException(40000, "手机号已存在");
        }

        // 4. 创建新用户
        User user = new User();
        BeanUtils.copyProperties(customerCreateDTO, user);
        
        // 设置默认密码（888888的MD5加密）
        String defaultPwd = DigestUtils.md5DigestAsHex("888888".getBytes());
        user.setPassword(defaultPwd);
        user.setIsAdmin(false); // 设置为普通用户
        
        // 手动设置时间
        LocalDateTime now = LocalDateTime.now();
        user.setCreateTime(now);
        user.setUpdateTime(now);

        // 5. 保存用户到数据库
        int result = userMapper.insert(user);
        if (result != 1) {
            throw new BusinessException(50001, "创建客户失败");
        }

        // 6. 自动为用户创建银行卡（调用已有的银行卡创建服务）
        CardCreateDTO cardCreateDTO = new CardCreateDTO();
        cardCreateDTO.setPid(user.getPid()); // 使用用户的身份证号
        cardCreateDTO.setDepositId(1); // 默认活期存款
        cardCreateDTO.setCurrency("RMB");
        cardCreateDTO.setOpenMoney(1.0);

        // 调用已有的银行卡创建服务
        cardManageService.createCard(cardCreateDTO);
        log.info("用户{}创建成功，银行卡创建成功", user.getUserId());
        return;
    }

    @Override
    public List<UserVO> listCustomers(Integer userId, String userName, String pid, String telephone, String address) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (userId != null) wrapper.eq("user_id", userId);
        if (userName != null && !userName.isEmpty()) wrapper.like("user_name", userName);
        if (pid != null && !pid.isEmpty()) wrapper.eq("pid", pid);
        if (telephone != null && !telephone.isEmpty()) wrapper.eq("telephone", telephone);
        if (address != null && !address.isEmpty()) wrapper.like("address", address);
        wrapper.eq("is_deleted", 0);
        List<User> users = userMapper.selectList(wrapper);
        List<UserVO> voList = new ArrayList<>();
        for (User user : users) {
            UserVO vo = new UserVO();
            BeanUtils.copyProperties(user, vo);
            voList.add(vo);
        }
        return voList;
    }

    @Override
    public PageResult<UserVO> pageCustomers(Integer page, Integer size, Integer userId, String userName, String pid, String telephone, String address) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (userId != null) wrapper.eq("user_id", userId);
        if (userName != null && !userName.isEmpty()) wrapper.like("user_name", userName);
        if (pid != null && !pid.isEmpty()) wrapper.eq("pid", pid);
        if (telephone != null && !telephone.isEmpty()) wrapper.eq("telephone", telephone);
        if (address != null && !address.isEmpty()) wrapper.like("address", address);
        wrapper.eq("is_deleted", 0);

        Page<User> pageObj = new Page<>(page, size);
        Page<User> userPage = userMapper.selectPage(pageObj, wrapper);

        List<UserVO> voList = new ArrayList<>();
        for (User user : userPage.getRecords()) {
            UserVO vo = new UserVO();
            BeanUtils.copyProperties(user, vo);
            voList.add(vo);
        }
        PageResult<UserVO> result = new PageResult<>();
        result.setTotal(userPage.getTotal());
        result.setPage((int) userPage.getCurrent());
        result.setSize((int) userPage.getSize());
        result.setRecords(voList);
        return result;
    }

    @Override
    public PageResult<UserVO> pageCustomers(CustomerQueryDTO queryDTO) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        
        // 用户ID查询
        if (queryDTO.getUserId() != null) {
            wrapper.eq("user_id", queryDTO.getUserId());
        }
        
        // 用户名查询
        if (queryDTO.getUserName() != null && !queryDTO.getUserName().trim().isEmpty()) {
            wrapper.like("user_name", queryDTO.getUserName().trim());
        }
        
        // 身份证号查询
        if (queryDTO.getPid() != null && !queryDTO.getPid().trim().isEmpty()) {
            wrapper.eq("pid", queryDTO.getPid().trim());
        }
        
        // 手机号查询
        if (queryDTO.getTelephone() != null && !queryDTO.getTelephone().trim().isEmpty()) {
            wrapper.eq("telephone", queryDTO.getTelephone().trim());
        }
        
        // 地址查询
        if (queryDTO.getAddress() != null && !queryDTO.getAddress().trim().isEmpty()) {
            wrapper.like("address", queryDTO.getAddress().trim());
        }
        
        // 管理员状态查询
        if (queryDTO.getIsAdmin() != null) {
            wrapper.eq("is_admin", queryDTO.getIsAdmin());
        }
        
        // 时间范围查询
        if (queryDTO.getStartTime() != null && !queryDTO.getStartTime().trim().isEmpty()) {
            try {
                LocalDate startDate = LocalDate.parse(queryDTO.getStartTime().trim());
                LocalDateTime startDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
                wrapper.ge("create_time", startDateTime);
            } catch (Exception e) {
                log.warn("Invalid startTime format: {}", queryDTO.getStartTime());
            }
        }
        if (queryDTO.getEndTime() != null && !queryDTO.getEndTime().trim().isEmpty()) {
            try {
                LocalDate endDate = LocalDate.parse(queryDTO.getEndTime().trim());
                LocalDateTime endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
                wrapper.le("create_time", endDateTime);
            } catch (Exception e) {
                log.warn("Invalid endTime format: {}", queryDTO.getEndTime());
            }
        }
        
        wrapper.eq("is_deleted", 0);
        wrapper.orderByDesc("create_time");

        Page<User> pageObj = new Page<>(queryDTO.getPage(), queryDTO.getSize());
        Page<User> userPage = userMapper.selectPage(pageObj, wrapper);

        List<UserVO> voList = new ArrayList<>();
        for (User user : userPage.getRecords()) {
            UserVO vo = new UserVO();
            BeanUtils.copyProperties(user, vo);
            voList.add(vo);
        }
        PageResult<UserVO> result = new PageResult<>();
        result.setTotal(userPage.getTotal());
        result.setPage((int) userPage.getCurrent());
        result.setSize((int) userPage.getSize());
        result.setRecords(voList);
        return result;
    }

    @Override
    @Transactional
    public boolean resetCustomerPassword(Integer userId) {
        // 查询用户
        User user = userMapper.selectById(userId);
        if (user == null || user.getIsDeleted()==1) {
            return false;
        }
        // 设置默认密码（888888的MD5加密）
        String defaultPwd = DigestUtils.md5DigestAsHex("888888".getBytes());
        user.setPassword(defaultPwd);
        int result = userMapper.updateById(user);
        return result == 1;
    }

    @Override
    @Transactional
    public String removeCustomer(Integer userId) {
        User user = userMapper.selectById(userId);
        if (user == null || user.getIsDeleted() == 1) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "客户不存在");
        }

        // 查询客户的银行卡
        QueryWrapper<Card> cardWrapper = new QueryWrapper<>();
        cardWrapper.eq("user_id", userId);
        cardWrapper.eq("is_deleted", 0);
        List<Card> cards = cardMapper.selectList(cardWrapper);

        // 删除银行卡（逻辑删除）
        int deletedCardCount = 0;
        for (Card card : cards) {
            // 检查银行卡余额，如果余额大于1元则不允许删除
            if (card.getBalance().compareTo(BigDecimal.ONE) > 0) {
                throw new BusinessException(40000, String.format("银行卡%s余额为%.2f元，大于1元，无法删除", card.getCardId(), card.getBalance()));
            }
            
            boolean result = cardMapper.deleteById(card.getCardId()) > 0;
            if (result) {
                deletedCardCount++;
            }
        }
        
        // 删除客户（逻辑删除）
        int result = userMapper.deleteById(userId);
        if (result != 1) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "删除客户失败");
        }

        log.info("客户{}删除成功，连带删除{}张银行卡", userId, deletedCardCount);

        // 返回删除结果信息
        if (deletedCardCount > 0) {
            return String.format("客户删除成功，连带删除%d张银行卡", deletedCardCount);
        } else {
            return "客户删除成功";
        }
    }

    @Override
    public void updateCustomer(CustomerUpdateDTO customerUpdateDTO) {
        User user = userMapper.selectById(customerUpdateDTO.getUserId());
        // 验证身份证号格式
        if (customerUpdateDTO.getPid() != null && !customerUpdateDTO.getPid().isEmpty()) {
            if (!customerUpdateDTO.getPid().matches("^\\d{17}[\\dXx]$")) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "身份证号格式不正确");
            }
        }
        
        // 验证手机号格式
        if (customerUpdateDTO.getTelephone() != null && !customerUpdateDTO.getTelephone().isEmpty()) {
            if (!customerUpdateDTO.getTelephone().matches("^\\d{11}$")) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式不正确");
            }
        }

        // 更新客户信息
        if (customerUpdateDTO.getUserName() != null) {
            user.setUserName(customerUpdateDTO.getUserName());
        }
        if (customerUpdateDTO.getPid() != null) {
            user.setPid(customerUpdateDTO.getPid());
        }
        if (customerUpdateDTO.getTelephone() != null) {
            user.setTelephone(customerUpdateDTO.getTelephone());
        }
        if (customerUpdateDTO.getAddress() != null) {
            user.setAddress(customerUpdateDTO.getAddress());
        }
        
        user.setUpdateTime(LocalDateTime.now());
        
        int result = userMapper.updateById(user);
        if (result != 1) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "更新失败");
        }
    }
} 